package main

import (
	"fmt"
)

type Listener func(taskId int32, eventAim int32, eventValue int32)

type EventObserver struct {
	flag      string
	listeners map[int32]map[int32]Listener
}

func NewEventObserver(flag string) *EventObserver {
	return &EventObserver{
		flag:      flag,
		listeners: make(map[int32]map[int32]Listener, 50),
	}
}

func (e *EventObserver) AddEventListener(eventType int32, taskId int32, listener Listener) {
	if _, ok := e.listeners[eventType]; !ok {
		e.listeners[eventType] = make(map[int32]Listener, 100)
	}
	value, _ := e.listeners[eventType]
	value[taskId] = listener
}

func (e *EventObserver) DispatchEvent(eventType int32, eventAim int32, eventValue int32) {
	fmt.Printf("DispatchEvent [%s] [%d-%d-%d]\n", e.flag, eventType, eventAim, eventValue)
	if value, ok := e.listeners[eventType]; ok {
		for taskId, listener := range value {
			listener(taskId, eventAim, eventValue)
		}
	}
}

func (e *EventObserver) RemoveEventListenerById(delTaskId int32) {
	fmt.Printf("RemoveEventListenerById [%s] delTaskId=%d start\n", e.flag, delTaskId)
	for _, value := range e.listeners {
		for taskId, _ := range value {
			if taskId == delTaskId {
				delete(value, taskId)
			}
		}
	}
	e.DumpAllEventListeners()
	fmt.Printf("RemoveEventListenerById [%s] delTaskId=%d end\n", e.flag, delTaskId)
}

func (e *EventObserver) RemoveEventListenerByEvent(eventType int32) {
	fmt.Printf("RemoveEventListenerByEvent [%s] eventType=%d start\n", e.flag, eventType)
	delete(e.listeners, eventType)
	e.DumpAllEventListeners()
	fmt.Printf("RemoveEventListenerByEvent [%s] eventType=%d end\n", e.flag, eventType)
}

func (e *EventObserver) DumpAllEventListeners() {
	for eventType, value := range e.listeners {
		for taskId, listener := range value {
			fmt.Printf("EventObserver dumpAllEventListeners() %s [%d-%d-%v]\n", e.flag, eventType, taskId, listener)
		}
	}
}

func receiveTaskTxEvent(taskId int32, eventAim int32, eventValue int32) {
	fmt.Println("receiveTaskTxEvent:", taskId, eventAim, eventValue)
}

func main() {
	event := NewEventObserver("task_rp")
	event.AddEventListener(10, 1, receiveTaskTxEvent)
	event.AddEventListener(10, 2, receiveTaskTxEvent)
	event.AddEventListener(11, 3, receiveTaskTxEvent)
	event.DumpAllEventListeners()
	event.DispatchEvent(10, 0, 1)
	event.DispatchEvent(9, 1001001, 1)

}
